/**
 * 1、Object.create( ref )
 * 2、Object.getOwnPropertyNames( ref )
 * 3、Object.isFrozen( ref )
 * 4、Object.freeze( ref )
 * 5、Object.keys( ref )
 */

// 创建一个不包含任何数据的实例
let x = Object.create( null );
console.log( x );

// 通过 "引用变量.属性名" 可以为 x 引用的 实例 声明 属性 或 函数
x.name = '王语嫣' ;
x.age = '18' ;
x.address = '燕子坞' ;
x.introduce = function(){
    console.log( '大家好，我是' + this.name + '，来自' + this.address + '，今年' + this.age);
}

console.log( x.name , x.age , x.address );
x.introduce();

console.log( '- - - - - - - - - - - - - - - - - - - - -' );

// 获得 引用变量 x 所指向的 堆内存 中的 实例 中所拥有的属性名
let propNames = Object.getOwnPropertyNames( x );
console.log( propNames );

for( let i = 0 ; i < propNames.length ; i++ ){
    let pn = propNames[ i ]; // 取 propNames 中下标是 i 的元素
    let pv = x[ pn ] ; // 获得 x 指向的实例中 指定名称 的属性值
    console.log( pn , pv );
}

console.log( '- - - - - - - - - - - - - - - - - - - - -' );

console.log( x );
// 删除 引用变量 x 所指向的 堆内存中实例 的 introduce 属性/函数
delete x.introduce ;
console.log( x );

// 注意这里有个感叹号
if( !Object.isFrozen( x ) ) { // 判断实例是否已经冻结
    Object.freeze( x ); // 冻结指定的实例
}

delete x.name ; // 可以执行，但你删不掉的
console.log( x );

console.log( '- - - - - - - - - - - - - - - - - - - - -' );

let keys = Object.keys( x );
console.log( keys );

for( let i = 0 ; i < keys.length ; i++ ){
    let pn = keys[ i ]; // 取 keys 中下标是 i 的元素
    let pv = x[ pn ] ; // 获得 x 指向的实例中 指定名称 的属性值
    console.log( pn , pv );
}